﻿using System;
using FluentAssertions;
using Xunit;

namespace Bogus.Tests.GitHubIssues;

public class Issue13 : SeededTest
{
   public class ReadOnly
   {
      public string Name;

      public string NameReadOnly => Name;
   }

   [Fact]
   public void issue_13_readonly_property()
   {
      var faker = new Faker<ReadOnly>()
         .StrictMode(true)
         .RuleFor(ro => ro.Name, f => f.Name.FirstName());

      faker.Validate().Should().BeTrue();
      faker.TypeProperties.Count.Should().Be(1);
   }

   [Fact]
   public void issue_13_with_model()
   {
      var counter = 0;

      var faker = new Faker<TestObject>()
         .StrictMode(true)
         .RuleFor(c => c.SomeOtherId, f => counter++)
         .RuleFor(c => c.SomeId, f => Guid.NewGuid())
         .RuleFor(c => c.SomeFutureDate, f => f.Date.Future())
         .RuleFor(c => c.SomePastDate, (f, b) => b.SomeFutureDate.AddHours(f.Random.Number(1, 24)))
         .RuleFor(c => c.SomeStatusInt, (f, b) => (int)b.SomeExplicitInt)
         .RuleFor(c => c.SomeExplicitInt, f => 2)
         .RuleFor(c => c.SomeBool3, f => f.Random.Bool())
         .RuleFor(c => c.SomeBool2, f => f.Random.Bool())
         .RuleFor(c => c.SomeBool1, f => f.Random.Bool())
         .RuleFor(c => c.SomeOtherInt, f => f.Random.Number(1, 5))
         .RuleFor(c => c.SomeInt, f => 0)
         .RuleFor(c => c.SomeOtherString, f => null)
         .RuleFor(c => c.SomeOtherGuid, f => Guid.NewGuid())
         .RuleFor(c => c.SomeString, f => null)
         .RuleFor(c => c.SomeComment, f => f.Lorem.Sentence())
         .RuleFor(c => c.SomeGuid, f => null)
         .RuleFor(c => c.SomeTimestamp, f => null);

      faker.TypeProperties.Count.Should().Be(17);

      var fake = faker.Generate();
      fake.Dump();
   }

   public class TestObject
   {
      private DateTime? _lastTimeToUnbook;

      public int SomeOtherId { get; set; }

      public Guid SomeId { get; set; }

      public DateTime SomeFutureDate { get; set; }

      public DateTime SomePastDate { get; set; }

      public int SomeStatusInt { get; set; }

      public int SomeExplicitInt
      {
         get { return this.SomeStatusInt; }
         set { this.SomeStatusInt = value; }
      }

      public bool SomeBool3 { get; set; }

      public bool SomeBool2 { get; set; }

      public bool SomeBool1 { get; set; }

      public int SomeOtherInt { get; set; }

      public DateTime? ReadOnlyDateTime
      {
         get { return _lastTimeToUnbook; }
      }

      public int SomeInt { get; set; }

      public string SomeOtherString { get; set; }

      public Guid SomeOtherGuid { get; set; }

      public string SomeString { get; set; }

      public bool Someboolean
      {
         get { return !this.SomeTimestamp.HasValue; }
      }

      public DateTime? SomeTimestamp { get; set; }

      public Guid? SomeGuid { get; set; }

      public string SomeComment { get; set; }
   }
}